package com.physics.mps.module.comsol.builder.physics;


import com.physics.mps.module.comsol.builder.Builder;
import com.physics.mps.module.comsol.enums.PhysicsEnum;
import com.physics.mps.module.comsol.vo.MultiPhysicsVo;
import com.physics.mps.module.comsol.vo.PhysicsFeature;
import com.physics.mps.module.comsol.vo.PhysicsVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;


/**
 * @author mcsoft
 * @date 2023/10/16 13:30
 * @description comsol java 物理场载荷脚本构建
 */
public class PhysicsBuilder {

    private static final String SET_PF_PROPERTY = "%s.set(\"%s\", \"%s\");";


    private final Builder builder;

    public PhysicsBuilder(Builder builder) {
        this.builder = builder;
    }

    public void build(String geomTag, List<PhysicsVo> vos) {
        if (CollectionUtils.isEmpty(vos)) {
            return;
        }
        for (PhysicsVo vo : vos) {
            build(geomTag, vo);
        }
    }

    public void build(String geomTag, PhysicsVo vo) {
        String physics = vo.getPhysics();
        String physicsAbbr = PhysicsEnum.getTag(physics);
        String physicsTag = builder.uniqueTag("physics");

        builder.change(2, 2);
        builder.append("Physics ");
        builder.append(physicsTag);
        builder.append(" = comp.physics().create(");
        builder.value(physicsAbbr);
        builder.append(", ");
        builder.value(physics);
        builder.append(", ");
        builder.value(geomTag);
        builder.append(");");

        createPhysicsFeature(physicsTag, geomTag, vo.getFeatures());
    }


    public void buildMultiPhysics(MultiPhysicsVo multiPhysicsVo) {
        if (null == multiPhysicsVo) {
            return;
        }
        builder.change(1, 2);
        builder.append("MultiphysicsCoupling multi = comp.multiphysics().create(");
        builder.value(multiPhysicsVo.getMultiPhysics());
        builder.append(", ");
        builder.value(multiPhysicsVo.getMultiPhysics());
        builder.append(", 3);");

        multiPhysicsVo.getPhysicsList().forEach(p -> {
            builder.change(1, 2);
            builder.append("multi.set(");
            builder.value(p.getMultiTag());
            builder.append(", ");
            builder.value(p.getTag());
            builder.append(");");
        });

        builder.change(1, 2);
        builder.append("multi.selection().all();");
    }


    /**
     * 创建物理场特征
     * @param physicsTag
     * @param geomTag
     * @param physicsFeatures
     */
    private void createPhysicsFeature(String physicsTag, String geomTag, List<PhysicsFeature> physicsFeatures) {
        if (CollectionUtils.isEmpty(physicsFeatures)) {
            return;
        }
        physicsFeatures.forEach(vo -> {
            builder.change(2, 2);
            String featureAddr = abbr(vo.getFeature());
            String featureAddrTag = builder.uniqueTag(featureAddr);

            createPhysicsFeature(physicsTag, featureAddrTag, vo);

            if (!vo.isSelectAll()) {
                builder.change(1, 2);
                String ballSelect = builder.createBallSelect(vo.getEntityDim(), vo.getCoordinate());
                builder.change(1, 2);
                builder.append(featureAddrTag);
                builder.append(".selection().named(");
                builder.append("\"");
                builder.append(geomTag);
                builder.append("_");
                builder.append(ballSelect);
                builder.append("\"");
                builder.append(");");
            } else {
                builder.change(1, 2);
                builder.append(featureAddrTag);
                builder.append(".selection().all();");
            }

            // 设置属性
            setProperty(featureAddrTag, vo.getProperties(), vo.getExtraProperty());

        });
    }


    /**
     * createPhysicsFeature
     * @param physicsTag
     * @param featureAddrTag
     * @param vo
     */
    private void createPhysicsFeature(String physicsTag, String featureAddrTag, PhysicsFeature vo) {
        builder.append("PhysicsFeature ");
        builder.append(featureAddrTag);
        builder.append(" = ");
        builder.append(physicsTag);
        if (!StringUtils.isEmpty(vo.getParentFeatureTag())) {
            builder.append(".feature(");
            builder.value(vo.getParentFeatureTag());
            builder.append(")");
        }
        builder.append(".create(");
        builder.value(featureAddrTag);
        builder.append(", ");
        builder.value(vo.getFeature());
        builder.append(", ");
        builder.append(vo.getEntityDim());
        builder.append(");");
    }


    /**
     * 设置属性
     * @param featureAddrTag
     * @param properties
     */
    private void setProperty(String featureAddrTag, Map<String, String> properties, String extraProperty){
        // 拓展属性处理
        if (!StringUtils.isEmpty(extraProperty)) {
            builder.change(1, 2);
            builder.append(featureAddrTag);
            builder.append(".");
            builder.append(extraProperty);
        }
        if(CollectionUtils.isEmpty(properties)) {
            return;
        }
        properties.forEach((key, value) -> {
            builder.change(1, 2);
            builder.append(String.format(SET_PF_PROPERTY, featureAddrTag, key, value));
        });
    }



    /**
     * 获取首字母缩写
     * @param str
     * @return
     */
    public String abbr(String str){
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isUpperCase(c)) {
                stringBuilder.append(Character.toLowerCase(c));
            }
        }
        if (stringBuilder.length() == 0) {
            return str;
        }
        return stringBuilder.toString();
    }


}
